package acwing._1_1AlgorithmBasic;

import java.util.Arrays;

/**
 * @Project : AlgorithmLearning
 * @Package : ACWing._1_1AlgorithmBasic
 * @File : _3_4MinimumSpanningTree.java
 * @Author : WangRuoyu
 * @Date : 2023/4/3 10:40
 */

public class _3_4MinimumSpanningTree {
    /*******朴素prim*******/
    static int prim(int[][] dis) {
        boolean[] st = new boolean[dis.length];
        int[] d = new int[dis.length];
        Arrays.fill(d, 0x3f3f3f3f);
        int res = 0;
        for (int i = 0; i < dis.length; ++i) { // 选择n个点，n-1条边
            int idx = -1;
            for (int j = 0; j < d.length; ++j) { // 选择距离连通图最近的点
                if ((idx == -1 || d[idx] > d[j]) && !st[j]) {
                    idx = j;
                }
            }
            if (i != 0 && d[idx] == 0x3f3f3f3f) {
                res = 0x3f3f3f3f;
                break;
            }
            st[idx] = true;
            if (i != 0) res += d[idx];

            for (int j = 0; j < dis.length; ++j) {
                d[j] = Math.min(d[j], dis[idx][j]); // 与dijkstra算法不同，更新到集合的距离，是dis[idx][j]而不是d[j]+dis[idx][j]
            }
        }
        return res;
    }

    /*******kruskal算法*******/
    static int find(int x, int[] p) {
        if (p[x] == x) return x;
        else {
            int father = find(p[x], p);
            p[x] = father;
            return father;
        }
    }

    static int kruskal(int[][] edges, int[] p) {
        int res = 0;
        int cnt = 0;

        for (int[] edge : edges) {
            int fa = find(edge[1], p);
            int fb = find(edge[2], p);
            if (fa != fb) {
                p[fa] = fb;
                res += edge[0];
                cnt++;
            }
        }

        if (cnt < p.length - 1) {
            res = 0x3f3f3f3f;
        }
        return res;
    }
}


